/**
 * 20220304:[require] to [import]...jordia
 */
import {Ray,Vector3} from 'three';
import DragLimit from "./drag-limit";


/**
 * 吸附点集拖动
 */
export default class DragPointsLimit extends DragLimit{
    constructor(values){
        super(values);
    }

    /**
     * 获取约束类型
     * @returns {string}
     */
    get type(){
        return 'dragPointsLimit';
    }

    /**
     * 获取点集
     * @returns {*|null|[*, *]}
     */
    get points(){
        return this._points;
    }

    /**
     * 设置点集
     * @param points
     */
    set points(points){
        this._points=points;
        this._setTrsPs();
    }

    /**
     * 获取变换矩阵
     * @returns {*|null}
     */
    get transform(){
        return this._transform;
    }

    /**
     * 设置点集的变换矩阵
     * @param mat4
     */
    set transform(mat4){
        this._transform=mat4;
        this._setTrsPs();
    }

    modifyMove(object,v,callback,camera) {
        camera.getWorldPosition(this._cameraPosition);
        this._tempDirection.subVectors(v, this._cameraPosition).normalize();
        this._tempRay.set(this._cameraPosition, this._tempDirection);

        let closestPoint=new Vector3();
        let md=Number.POSITIVE_INFINITY;
        for(let p of this._trsPs){
            let ds=this._tempRay.distanceSqToPoint(p);
            if(ds<md){
                md=ds;
                closestPoint.copy(p);
            }
        }

        this._transformVector(object,closestPoint);
        object.position.copy(closestPoint);
        callback(object,closestPoint);
    }
    dispose(){
        super.dispose();
        this._points=null;
        this._transform=null;
        this._trsPs=null;
        this._cameraPosition=null;
        this._tempDirection=null;
        this._tempRay=null;
    }

    /**
     * 更新用于检测最近点的顶点集
     * @private
     */
    _setTrsPs(){
        this._trsPs.length=0;
        if(this._transform){
            for(let p of this._points){
                let t=new Vector3().copy(p);
                t.applyMatrix4(this._transform);
                this._trsPs.push(t);
            }
        }else{
            for(let p of this._points){
                let t=new Vector3().copy(p);
                this._trsPs.push(t);
            }
        }
    }

    _initVariable() {
        super._initVariable();
        this._points=[new Vector3(0,0,0),new Vector3(1,0,0)];
        this._transform=null;
        this._trsPs=[new Vector3(0,0,0),new Vector3(1,0,0)];

        this._cameraPosition=new Vector3();
        this._tempDirection=new Vector3();
        this._tempRay=new Ray();
    }
}